package com.liqiye.paymanager.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.liqiye.paymanager.config.PaymentProperties;
import com.paypal.sdk.PaypalServerSdkClient;
import com.paypal.sdk.controllers.OrdersController;
import com.paypal.sdk.exceptions.ApiException;
import com.paypal.sdk.http.response.ApiResponse;
import com.paypal.sdk.models.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.UUID;


/**
 * paypal-acdc
 */
@Slf4j
@RestController
@RequestMapping("/paypal")
public class PaypalACDCController {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private PaypalServerSdkClient client;

    @Autowired
    private PaymentProperties config;

    @Autowired
    private RestTemplate restTemplate;

//    private final String baseUrl = "https://api-m.sandbox.paypal.com";
    private final String baseUrl = "https://api-m.paypal.com";


    @PostMapping("/api/orders")
    public ResponseEntity<Order> createOrder(@RequestBody Map<String, Object> request) {
        try {
            String cart = objectMapper.writeValueAsString(request.get("cart"));
            Order response = createOrder(cart);
            return new ResponseEntity<>(response, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PostMapping("/api/orders/{orderID}/capture")
    public ResponseEntity<Order> captureOrder(@PathVariable String orderID) {
        try {
            Order response = captureOrders(orderID);
            return new ResponseEntity<Order>(response, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    private Order createOrder(String cart) throws IOException, ApiException {

        CreateOrderInput createOrderInput = new CreateOrderInput.Builder(
                null,
                new OrderRequest.Builder(
                        CheckoutPaymentIntent.CAPTURE,
                        Arrays.asList(
                                new PurchaseUnitRequest.Builder(
                                        new AmountWithBreakdown.Builder(
                                                "USD",
                                                "100.00")
                                                .build())
                                        .build()))
                        .build())
                .build();

        OrdersController ordersController = client.getOrdersController();

        ApiResponse<Order> apiResponse = ordersController.createOrder(createOrderInput);

        return apiResponse.getResult();
    }

    private Order captureOrders(String orderID) throws IOException, ApiException {
        CaptureOrderInput ordersCaptureInput = new CaptureOrderInput.Builder(
                orderID,
                null)
                .build();
        OrdersController ordersController = client.getOrdersController();
        ApiResponse<Order> apiResponse = ordersController.captureOrder(ordersCaptureInput);
        return apiResponse.getResult();
    }


    /**
     * 首单：创建订单，并指示保存卡到 vault（ON_SUCCESS）
     * 前端用这个 orderId 调用 CardFields.submit() 完成支付
     */
    @PostMapping("/api/token-payments")
    public ResponseEntity<Object> createTokenPayment(@RequestBody Map<String, Object> body) {

        try {
            String amount = body.getOrDefault("amount","2.90").toString();
            String currency = body.getOrDefault("currency","USD").toString();

            ObjectNode root = objectMapper.createObjectNode();
            root.put("intent","CAPTURE");

            // 指示在成功支付后把卡存到 vault
            ObjectNode paymentSource = root.putObject("payment_source");
            ObjectNode card = paymentSource.putObject("card");
            ObjectNode attributes = card.putObject("attributes");
            ObjectNode vault = attributes.putObject("vault");
            vault.put("store_in_vault","ON_SUCCESS"); // 或 "ON_APPROVAL"
            // 可选：usage_type 表示 vault 的使用类型（MERCHANT/CUSTOMER）
             vault.put("usage_type","MERCHANT");

            // purchase_units
            ArrayNode pus = root.putArray("purchase_units");
            ObjectNode pu = pus.addObject();
            ObjectNode amt = pu.putObject("amount");
            pu.put("custom_id", "我们的outRequestNo");
            amt.put("currency_code", currency);
            amt.put("value", amount);

            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>(objectMapper.writeValueAsString(root), headers);
            ResponseEntity<String> resp = restTemplate.postForEntity(baseUrl + "/v2/checkout/orders", req, String.class);


            JsonNode orderNode = objectMapper.readTree(resp.getBody());
            String id = orderNode.get("id").asText();
            System.out.println("首单orderId: " + id);


            return ResponseEntity.status(resp.getStatusCode()).body(resp.getBody());



        } catch (HttpClientErrorException e) {
            log.error("createOrderSaveCard error body={}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("createOrderSaveCard exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }

    }


    /**
     * 完成扣款（首付完成后，获取授权 token）
     */
    @PostMapping("/api/token-payments/{orderId}/capture")
    public ResponseEntity<Object> captureTokenPayment(@PathVariable String orderId) {
        try {
            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>("{}", headers);
            ResponseEntity<String> resp = restTemplate.postForEntity(baseUrl + "/v2/checkout/orders/" + orderId + "/capture", req, String.class);

            JsonNode orderNode = objectMapper.readTree(resp.getBody());

            String id = orderNode.get("id").asText();
//            System.out.println("首单orderId: " + id);

            // 尝试获取 vault id（如果直接 VAULTED，会在 response 里）（这个就是续费的凭证）
            JsonNode vaultIdNode = orderNode.at("/payment_source/card/attributes/vault/id");
            String vaultId = vaultIdNode.isMissingNode() ? null : vaultIdNode.asText(null);
            System.out.println("vaultId（续费凭证）: " + vaultId);


            JsonNode captureIdNode = orderNode.at("/purchase_units/0/payments/captures/0/id");
            JsonNode captureStatusNode = orderNode.at("/purchase_units/0/payments/captures/0/status");
            String captureId = captureIdNode.isMissingNode() ? null : captureIdNode.asText(null);
            String captureStatus = captureStatusNode.isMissingNode() ? null : captureStatusNode.asText();
            System.out.println("captureId（首单退款凭证）: " + captureId);
            if (!"COMPLETED".equals(captureStatus)) {
                // DECLINED / PENDING → 业务上要当失败处理
                System.out.println("首单失败");
            }else{
                System.out.println("首单成功");
            }


            // 如果 vault 状态是 APPROVED 而非 VAULTED，需要等待 webhook VAULT.PAYMENT-TOKEN.CREATED
            JsonNode vaultStatus = orderNode.at("/payment_source/card/attributes/vault/status");
            String vaultStatusStr = vaultStatus.isMissingNode() ? null : vaultStatus.asText();

            ObjectNode result = objectMapper.createObjectNode();
            result.set("order", orderNode);
            if (vaultId != null) result.put("vaultId", vaultId);
            if (vaultStatusStr != null) result.put("vault_status", vaultStatusStr);
            if ("APPROVED".equalsIgnoreCase(vaultStatusStr)) {
                result.put("note", "vault token not immediate; subscribe to VAULT.PAYMENT-TOKEN.CREATED webhook to get vault_id");
            }

            return ResponseEntity.ok(result);

        } catch (HttpClientErrorException e) {
            log.error("captureForVault error body={}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("captureForVault exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }


    }


    public String getAccessToken() {
        PaymentProperties.PayPal paypal = config.getPaypal();
        String clientId = paypal.getClientId();
        String clientSecret = paypal.getClientSecret();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.setBasicAuth(clientId, clientSecret);

        MultiValueMap<String,String> body = new LinkedMultiValueMap<>();
        body.add("grant_type","client_credentials");

        HttpEntity<MultiValueMap<String,String>> req = new HttpEntity<>(body, headers);
        ResponseEntity<String> resp = restTemplate.postForEntity(baseUrl + "/v1/oauth2/token", req, String.class);

        try {
            JsonNode node = objectMapper.readTree(resp.getBody());
            return node.get("access_token").asText();
        } catch (Exception e) {
            throw new RuntimeException("getAccessToken error: " + e.getMessage(), e);
        }
    }




    /**
     * 后续扣款（续费）
     */
    @PostMapping("/api/token-payments/charge")
    public ResponseEntity<Object> chargeSavedToken(@RequestBody Map<String, Object> body) {
        try {
            String vaultId = body.get("vaultId").toString();
            String amount = body.getOrDefault("amount","66.00").toString();
            String currency = body.getOrDefault("currency","USD").toString();


            // 可选 previousTransactionReference 如果需要（network token MIT 场景）
//            String prevRef = body.getOrDefault("previousTransactionReference","").toString();

            ObjectNode root = objectMapper.createObjectNode();
            root.put("intent","CAPTURE");

            // payment_source.card.vault_id + stored_credential
            ObjectNode paymentSource = root.putObject("payment_source");
            ObjectNode card = paymentSource.putObject("card");
            card.put("vault_id", vaultId);

            // stored_credential for merchant-initiated subsequent
            ObjectNode stored = card.putObject("stored_credential");
            stored.put("payment_initiator","MERCHANT");
            stored.put("payment_type","RECURRING"); // 或 "ONE_OFF" 按需
            stored.put("usage","SUBSEQUENT");
//            if (!prevRef.isEmpty()) stored.put("previous_transaction_reference", prevRef);

            ArrayNode pus = root.putArray("purchase_units");
            ObjectNode pu = pus.addObject();
            ObjectNode amt = pu.putObject("amount");
            pu.put("custom_id", "我们的outRequestNo" + UUID.randomUUID());
            amt.put("currency_code", currency);
            amt.put("value", amount);

            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>(objectMapper.writeValueAsString(root), headers);
            ResponseEntity<String> resp = restTemplate.postForEntity(baseUrl + "/v2/checkout/orders", req, String.class);

            JsonNode createResp = objectMapper.readTree(resp.getBody());
            String orderId = createResp.get("id").asText();
            System.out.println("续费orderId: " + orderId);

            JsonNode captureStatusNode = createResp.at("/purchase_units/0/payments/captures/0/status");
            JsonNode captureIdNode = createResp.at("/purchase_units/0/payments/captures/0/id");
            String captureId = captureIdNode.isMissingNode() ? null : captureIdNode.asText(null);
            String captureStatus = captureStatusNode.isMissingNode() ? null : captureStatusNode.asText();

            System.out.println("captureId（续费退款凭证）: " + captureId);
            if (!"COMPLETED".equals(captureStatus)) {
                // DECLINED / PENDING → 业务上要当失败处理
                System.out.println("续费失败");
            }else{
                System.out.println("续费成功");
            }

            return ResponseEntity.status(resp.getStatusCode()).body(createResp);




            // 立刻 capture
//            HttpEntity<String> capReq = new HttpEntity<>("{}", headers);
//            ResponseEntity<String> capResp = restTemplate.postForEntity(baseUrl + "/v2/checkout/orders/"+orderId+"/capture", capReq, String.class);
//
//            JsonNode orderNode = objectMapper.readTree(capResp.getBody());
//
//            JsonNode captureStatusNode = orderNode.at("/purchase_units/0/payments/captures/0/status");
//            JsonNode captureIdNode = orderNode.at("/purchase_units/0/payments/captures/0/id");
//            String captureId = captureIdNode.isMissingNode() ? null : captureIdNode.asText(null);
//            String captureStatus = captureStatusNode.isMissingNode() ? null : captureStatusNode.asText();
//
//            System.out.println("captureId（续费退款凭证）: " + captureId);
//            if (!"COMPLETED".equals(captureStatus)) {
//                // DECLINED / PENDING → 业务上要当失败处理
//                System.out.println("续费失败");
//            }else{
//                System.out.println("续费成功");
//            }


//            return ResponseEntity.status(capResp.getStatusCode()).body(orderNode);



        } catch (HttpClientErrorException e) {
            log.error("续费失败 {}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("续费失败 ", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }

    }




    @PostMapping("/api/token-payments/refund")
    public ResponseEntity<Object> refundPayment(@RequestBody Map<String, Object> body) {
        try {
            String captureId = body.get("captureId").toString(); // 必填
            String amount = body.getOrDefault("amount", "").toString(); // 可选：部分退款
            String currency = body.getOrDefault("currency", "USD").toString();

            ObjectNode root = objectMapper.createObjectNode();
            if (!amount.isEmpty()) {
                ObjectNode amt = root.putObject("amount");
                amt.put("currency_code", currency);
                amt.put("value", amount);
            }

            String token = getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>(objectMapper.writeValueAsString(root), headers);
            ResponseEntity<String> resp = restTemplate.postForEntity(
                    baseUrl + "/v2/payments/captures/" + captureId + "/refund",
                    req,
                    String.class
            );

            JsonNode jsonNode = objectMapper.readTree(resp.getBody());
            return ResponseEntity.status(resp.getStatusCode()).body(jsonNode);

        } catch (HttpClientErrorException e) {
            log.error("refundPayment error body={}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("refundPayment exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }


    /**
     * 取消订阅
     */
    @PostMapping("/api/token-payments/cancelsubscription")
    public ResponseEntity<Object> cancelSubscription(@RequestBody Map<String, Object> body) {
        try {
            String vaultId = body.get("vaultId").toString();
            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>(headers);

            // 使用 DELETE 方法删除 vault token
            ResponseEntity<String> resp = restTemplate.exchange(
                    baseUrl + "/v3/vault/payment-tokens/" + vaultId,
                    HttpMethod.DELETE,
                    req,
                    String.class
            );

            // 如果删除成功，返回 204 No Content
            if (resp.getStatusCode() == HttpStatus.NO_CONTENT) {
                System.out.println("退订成功");
                return ResponseEntity.noContent().build();
            }
            System.out.println("退订失败");
            return ResponseEntity.status(resp.getStatusCode()).body(resp.getBody());

        } catch (HttpClientErrorException e) {
            log.error("deleteVaultToken error body={}", e.getResponseBodyAsString());

            // 如果凭证不存在或其他错误，返回相应的错误信息
            if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body("Payment token not found");
            }

            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("deleteVaultToken exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }

    }
















    /**
     * 停用支付令牌
     */
    @PostMapping("/api/token-payments/{vaultId}/disable")
    public ResponseEntity<Object> disableVaultToken(@PathVariable String vaultId) {
        try {
            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            // 创建禁用请求体
            ObjectNode requestBody = objectMapper.createObjectNode();
            requestBody.put("operation", "REPLACE");
            requestBody.put("path", "/status");
            requestBody.put("value", "INACTIVE");

            ArrayNode patches = objectMapper.createArrayNode();
            patches.add(requestBody);

            HttpEntity<String> req = new HttpEntity<>(objectMapper.writeValueAsString(patches), headers);

            // 使用PATCH方法更新令牌状态
            ResponseEntity<String> resp = restTemplate.exchange(
                    baseUrl + "/v3/vault/payment-tokens/" + vaultId,
                    HttpMethod.PATCH,
                    req,
                    String.class
            );

            return ResponseEntity.ok(resp.getBody());

        } catch (HttpClientErrorException e) {
            log.error("disableVaultToken error: {}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("disableVaultToken exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    /**
     * 重新启用支付令牌
     */
    @GetMapping("/api/token-payments/{vaultId}/enable")
    public ResponseEntity<Object> enableVaultToken(@PathVariable String vaultId) {
        try {
            String graphqlMutation = String.format(
                    "mutation { " +
                            "  updatePaymentToken(input: { " +
                            "    id: \"%s\", " +
                            "    patch: { " +
                            "      status: ACTIVE " +
                            "    } " +
                            "  }) { " +
                            "    paymentToken { " +
                            "      id " +
                            "      status " +
                            "      customerId " +
                            "    } " +
                            "  } " +
                            "}",
                    vaultId
            );

            ObjectNode request = objectMapper.createObjectNode();
            request.put("query", graphqlMutation);

            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>(objectMapper.writeValueAsString(request), headers);

            ResponseEntity<String> resp = restTemplate.postForEntity(
                    baseUrl + "/v3/graphql",
                    req,
                    String.class
            );

            JsonNode response = objectMapper.readTree(resp.getBody());

            if (response.has("errors")) {
                log.error("Enable vault token error: {}", response.get("errors"));
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
            }

            return ResponseEntity.ok(response);

        } catch (HttpClientErrorException e) {
            log.error("enableVaultToken error: {}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("enableVaultToken exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }

    /**
     * 获取支付令牌状态
     */
    @GetMapping("/api/token-payments/{vaultId}/status")
    public ResponseEntity<Object> getVaultTokenStatus(@PathVariable String vaultId) {
        try {
            String graphqlQuery = String.format(
                    "query { " +
                            "  paymentToken(id: \"%s\") { " +
                            "    id " +
                            "    status " +
                            "    customerId " +
                            "    paymentSource { " +
                            "      ... on Card { " +
                            "        lastDigits " +
                            "        brand " +
                            "        expiry " +
                            "      } " +
                            "    } " +
                            "    createdAt " +
                            "    updatedAt " +
                            "  } " +
                            "}",
                    vaultId
            );

            ObjectNode request = objectMapper.createObjectNode();
            request.put("query", graphqlQuery);

            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<String> req = new HttpEntity<>(objectMapper.writeValueAsString(request), headers);

            ResponseEntity<String> resp = restTemplate.postForEntity(
                    baseUrl + "/v3/graphql",
                    req,
                    String.class
            );

            JsonNode response = objectMapper.readTree(resp.getBody());

            if (response.has("errors")) {
                log.error("Get vault token status error: {}", response.get("errors"));
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
            }

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("getVaultTokenStatus exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }
    }





    @GetMapping("/get")
    public ResponseEntity<Object> get(String orderId) {
        String token = getAccessToken();
        HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(token);
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

        HttpEntity<String> req = new HttpEntity<>(headers);
        ResponseEntity<String> resp = restTemplate.exchange(
                baseUrl + "/v2/checkout/orders/" + orderId,
                HttpMethod.GET,
                req,
                String.class
        );
        String body = resp.getBody();
        System.out.println(body);
        return ResponseEntity.ok(body);
    }



    @GetMapping("/clientToken")
    public ResponseEntity<Object> clientToken() {

        try {
            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>(headers);
            ResponseEntity<String> resp = restTemplate.postForEntity(baseUrl + "/v1/identity/generate-token", req, String.class);


            JsonNode orderNode = objectMapper.readTree(resp.getBody());


            return ResponseEntity.status(resp.getStatusCode()).body(resp.getBody());



        } catch (HttpClientErrorException e) {
            log.error("createOrderSaveCard error body={}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("createOrderSaveCard exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }

    }

    @GetMapping("/check")
    public ResponseEntity<Object> check() {

        try {
            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>(headers);
            ResponseEntity<String> resp = restTemplate.exchange(
                    "https://api-m.paypal.com/v1/identity/oauth2/userinfo?schema=paypalv1.1",
                    HttpMethod.GET,
                    req,
                    String.class
            );


            JsonNode orderNode = objectMapper.readTree(resp.getBody());


            return ResponseEntity.status(resp.getStatusCode()).body(resp.getBody());



        } catch (HttpClientErrorException e) {
            log.error("createOrderSaveCard error body={}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("createOrderSaveCard exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }

    }

    @GetMapping("/checkvault")
    public ResponseEntity<Object> checkvault(String id) {
        System.out.println("=======" + id);

        try {
            String token = this.getAccessToken();
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("PayPal-Request-Id", UUID.randomUUID().toString());

            HttpEntity<String> req = new HttpEntity<>(headers);
            ResponseEntity<String> resp = restTemplate.exchange(
                    "https://api-m.paypal.com/v3/vault/payment-tokens/" + id,
                    HttpMethod.GET,
                    req,
                    String.class
            );


            JsonNode orderNode = objectMapper.readTree(resp.getBody());


            return ResponseEntity.status(resp.getStatusCode()).body(resp.getBody());



        } catch (HttpClientErrorException e) {
            log.error("createOrderSaveCard error body={}", e.getResponseBodyAsString());
            return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsString());
        } catch (Exception e) {
            log.error("createOrderSaveCard exception", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
        }

    }















}
